import re
from xmlrpc.client import MAXINT

from PyQt5.QtCore import QObject, QDateTime
from PyQt5.QtWidgets import QMessageBox

class TimeConverterModel(QObject):
    def __init__(self, ui):
        super().__init__()
        self.ui = ui
        self.last_valid_hex = ""
        self.MAXINT = MAXINT
        self.setup_connections()

    def setup_connections(self):
        self.ui.start_time.dateTimeChanged.connect(self.update_from_time)
        self.ui.end_time.dateTimeChanged.connect(self.update_from_time)
        self.ui.seconds_input.valueChanged.connect(self.update_from_seconds)
        self.ui.hex_io.textEdited.connect(self.update_from_hex)
        self.ui.byte_order.currentIndexChanged.connect(self.update_hex_display)
        self.ui.update_time_button.clicked.connect(self.update_current_time)

    def update_current_time(self):
        self.ui.end_time.setDateTime(QDateTime.currentDateTime())
        self.update_from_time()

    def validate_time_range(self):
        start = self.ui.start_time.dateTime().toSecsSinceEpoch()
        end = self.ui.end_time.dateTime().toSecsSinceEpoch()
        seconds = end - start
        if seconds < 0:
            QMessageBox.warning(self.ui, "错误", "起始时间不能大于结束时间")
            self.ui.end_time.setDateTime(self.ui.start_time.dateTime())
            return False
        elif seconds > self.MAXINT:
            QMessageBox.warning(self.ui, "错误",
                                 f"时间差超过32位整数最大值{self.MAXINT}秒)")
            self.ui.end_time.setDateTime(self.ui.start_time.dateTime().addSecs(self.MAXINT))
            return False
        return True

    def update_from_time(self):
        if self.validate_time_range():
            t1 = self.ui.start_time.dateTime().toSecsSinceEpoch()
            t2 = self.ui.end_time.dateTime().toSecsSinceEpoch()
            self.ui.seconds_input.setValue(t2 - t1)
            self.update_hex_display()

    def update_from_seconds(self):
        seconds = self.ui.seconds_input.value()
        new_time = self.ui.start_time.dateTime().addSecs(seconds)
        self.ui.end_time.setDateTime(new_time)
        self.update_hex_display()

    def format_hex(self, hex_str):
        hex_str = re.sub(r'[^0-9a-fA-F]', '', hex_str)
        hex_str = hex_str.zfill(8)
        return ' '.join([hex_str[i:i + 2] for i in range(0, len(hex_str), 2)])

    def validate_hex(self, hex_str):
        return bool(re.fullmatch(r'^[0-9a-fA-F ]*$', hex_str))

    def update_from_hex(self):
        hex_str = self.ui.hex_io.text()
        hex_clean = re.sub(r'[^0-9a-fA-F]', '', hex_str)

        # 输入长度检查
        if len(hex_clean) > 8:
            QMessageBox.warning(self.ui, "输入错误",
                                "16进制值不能超过4字节(8字符)",
                                QMessageBox.Ok)
            self.ui.hex_io.setText(self.last_valid_hex)
            return

        try:
            if hex_clean:  # 非空输入处理
                # 数值范围检查
                value = int(hex_clean, 16)
                if value > 0xFFFFFFFF:
                    raise ValueError("数值超出32位无符号整数范围")

                # 字节序处理
                if self.ui.byte_order.currentText() == "小端序":
                    bytes_data = bytes.fromhex(hex_clean.zfill(8))
                    value = int.from_bytes(bytes_data, 'little')

                # 更新秒数输入框
                self.ui.seconds_input.setValue(value)

                # 格式化显示
                formatted_hex = ' '.join([hex_clean[i:i + 2]
                                          for i in range(0, len(hex_clean), 2)])
                self.last_valid_hex = formatted_hex

        except ValueError as e:
            QMessageBox.critical(self.ui, "转换错误",
                                 f"无效的16进制输入: {str(e)}",
                                 QMessageBox.Ok)
            self.ui.hex_io.setText(self.last_valid_hex)
        except Exception as e:
            QMessageBox.critical(self.ui, "系统错误",
                                 f"处理16进制时发生意外错误: {str(e)}",
                                 QMessageBox.Ok)
            self.ui.hex_io.setText(self.last_valid_hex)

    def update_hex_display(self):
        seconds = self.ui.seconds_input.value()
        hex_str = format(seconds, '08x')
        if self.ui.byte_order.currentText() == "小端序":
            bytes_data = seconds.to_bytes(4, 'little')
            hex_str = bytes_data.hex()
        self.last_valid_hex = self.format_hex(hex_str)
        self.ui.hex_io.setText(self.last_valid_hex)